// pages/Cal/Cal.js
// 计算器页面逻辑
Page({
  // 页面数据初始化
  /**
   * 页面的初始数据
   */
    // 页面数据对象
  data: {
    // 按钮ID定义
    id_back: "back",  // 退格按钮ID
    id_clear: "clear",  // 清屏按钮ID
    id_opo: "opo",  // 正负号切换按钮ID
    id_plus: "plus",  // 加号按钮ID
    id_minus: "minus",  // 减号按钮ID
    id_multiply: "multiply",  // 乘号按钮ID
    id_divide: "divide",  // 除号按钮ID
    id_url: "url",  // 历史记录按钮ID
    id_equal: "equal",  // 等于按钮ID
    // 数字按钮ID
    id_1: "1",  // 数字1按钮ID
    id_2: "2",  // 数字2按钮ID
    id_3: "3",  // 数字3按钮ID
    id_4: "4",  // 数字4按钮ID
    id_5: "5",  // 数字5按钮ID
    id_6: "6",  // 数字6按钮ID
    id_7: "7",  // 数字7按钮ID
    id_8: "8",  // 数字8按钮ID
    id_9: "9",  // 数字9按钮ID
    id_0: "0",  // 数字0按钮ID
    id_dot: ".",  // 小数点按钮ID
    id_his: "history",  // 历史记录按钮ID
    // 计算器状态数据
    screenData: "0",  // 重置屏幕显示为0  // 当前屏幕显示的数据
    expressionData: "0",  // 重置表达式显示为0 // 用于显示完整计算表达式
    lastIsOperator: false,  // 重置运算符标记  // 标记上一个输入是否为运算符
    hasDecimalPoint: false,  // 重置小数点标记  // 标记当前数字是否已包含小数点
    num1: "",  // 清空第一个操作数  // 第一个操作数
    num2: "",  // 清空第二个操作数  // 第二个操作数
    operator: "",  // 清空当前运算符  // 当前运算符
    isReadyForNewNum: false,  // 重置新数字准备状态  // 标记是否准备输入新数字
    completeExpression: ""  // 清空完整表达式  // 用于存储完整的计算表达式
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    
  },

  /**
   * 清除屏幕内容
   * 重置所有计算器状态为初始值
   */
  clearScreen() {
    // 重置所有数据到初始状态
    // 更新页面数据
    this.setData({
      // 计算器状态数据
      screenData: "0",  // 重置屏幕显示为0  // 当前屏幕显示的数据
      expressionData: "0",  // 重置表达式显示为0
      lastIsOperator: false,  // 重置运算符标记  // 标记上一个输入是否为运算符
      hasDecimalPoint: false,  // 重置小数点标记  // 标记当前数字是否已包含小数点
      num1: "",  // 清空第一个操作数  // 第一个操作数
      num2: "",  // 清空第二个操作数  // 第二个操作数
      operator: "",  // 清空当前运算符  // 当前运算符
      isReadyForNewNum: false,  // 重置新数字准备状态  // 标记是否准备输入新数字
      completeExpression: ""  // 清空完整表达式
    });
  },

  /**
   * 处理退格操作
   * 删除屏幕显示的最后一个字符
   * 如果删除的是小数点，更新hasDecimalPoint状态
   */
  handleBackspace() {
    let { screenData, expressionData } = this.data; // 解构赋值获取当前数据
    
    if (screenData === "0" || screenData.length === 1) {
      // 如果屏幕上只有一个字符，设为0
      // 更新页面数据
    this.setData({ 
        // 计算器状态数据
        screenData: "0",  // 重置屏幕显示为0  // 当前屏幕显示的数据 
        expressionData: "0",  // 重置表达式显示为0
        hasDecimalPoint: false // 重置小数点标记  // 标记当前数字是否已包含小数点
      });
      return;
    }
    
    // 删除最后一个字符
    const lastChar = screenData.charAt(screenData.length - 1); // 获取最后一个字符
    if (lastChar === ".") {
      // 更新页面数据
      this.setData({ hasDecimalPoint: false });
    }
    screenData = screenData.substring(0, screenData.length - 1); // 删除最后一个字符
    // 同时更新expressionData
    if (this.data.completeExpression === "") {
      expressionData = screenData; // 直接使用screenData更新expressionData
    }
    
    // 更新页面数据
    this.setData({ 
      screenData, // 更新屏幕显示的数据
      expressionData // 更新表达式显示的数据
    });
  },

  /**
   * 处理正负号切换
   * 在屏幕显示的数字前添加或移除负号
   */
  toggleSign() {
    let { screenData, expressionData } = this.data;
    if (screenData === "0") return;
    if (screenData.charAt(0) === "-") {
      screenData = screenData.substring(1);
    } else {
      screenData = "-" + screenData;
    }
    
    // 同时更新expressionData
    if (this.data.completeExpression === "") {
      expressionData = screenData;
    }
    
    // 更新页面数据
    this.setData({ 
      screenData, // 更新屏幕显示的数据
      expressionData // 更新表达式显示的数据
    });
  },

  /**
   * 处理数字输入
   * @param {string} num - 输入的数字字符(0-9)
   * 根据当前状态决定是替换还是追加数字
   */
  appendNumber(num) {
    let { screenData, expressionData, isReadyForNewNum, completeExpression } = this.data;
    if (screenData === "0" || isReadyForNewNum) {
      // 如果屏幕显示为0或准备输入新数字，则替换显示内容
      screenData = num;  // 替换为新输入的数字
      isReadyForNewNum = false; // 重置新数字准备状态
    } else {
      // 否则追加数字
      screenData += num;
    }
    
    // 更新expressionData
    if (completeExpression) {
      // 如果已经有完整表达式，则更新为当前数字
      expressionData = completeExpression + screenData;
    } else {
      expressionData = screenData; // 直接使用screenData更新expressionData
    }
    
    // 更新页面数据
    this.setData({
      screenData, // 更新屏幕显示的数据
      expressionData, // 更新表达式显示的数据
      isReadyForNewNum: false // 重置新数字准备状态
    });
  },

  /**
   * 处理小数点输入
   * 确保每个数字最多只能有一个小数点
   * 如果准备输入新数字，自动在前面补0
   */
  appendDecimalPoint() {
    let { screenData, expressionData, hasDecimalPoint, isReadyForNewNum, completeExpression } = this.data;
    
    if (isReadyForNewNum) {
      // 如果准备输入新数字，先显示0.
      screenData = "0."; // 显示0.
      hasDecimalPoint = true;  // 标记当前数字已包含小数点
      isReadyForNewNum = false; // 重置新数字准备状态
    } else if (!hasDecimalPoint) {
      // 如果当前数字没有小数点，添加小数点
      screenData += ".";  // 追加小数点
      hasDecimalPoint = true;  // 标记当前数字已包含小数点
    }
    
    // 更新expressionData
    if (completeExpression) {
      expressionData = completeExpression + screenData;
    } else {
      expressionData = screenData;
    }
    
    // 更新页面数据
    this.setData({
      screenData,  // 更新屏幕显示的数据
      expressionData, // 更新表达式显示的数据
      hasDecimalPoint, // 更新小数点标记
      isReadyForNewNum: false // 重置新数字准备状态
    });
  },

  /**
   * 处理运算符输入
   * @param {string} op - 运算符类型(plus/minus/multiply/divide)
   * 如果有未完成的计算，先计算中间结果
   * 更新操作符并准备接收第二个操作数
   */
  handleOperator(op) {
    let { screenData, expressionData, num1, operator, completeExpression } = this.data;
    let operatorSymbol = this.getOperatorSymbol(op);
    
    // 如果已经有操作符和第一个数字，计算中间结果
    if (num1 !== "" && operator !== "" && !this.data.isReadyForNewNum) {
      const result = this.calculate(num1, screenData, operator);
      
      // 更新显示
      screenData = result;
      num1 = result;
      
      // 更新表达式
      completeExpression = result + " " + operatorSymbol + " ";
      expressionData = completeExpression;
    } else {
      num1 = screenData;
      
      // 更新表达式
      completeExpression = screenData + " " + operatorSymbol + " ";
      expressionData = completeExpression;
    }
    
    // 保存操作符并准备输入下一个数字
    // 更新页面数据
    this.setData({
      screenData, // 更新屏幕显示的数据
      expressionData, // 更新表达式显示的数据
      num1, // 更新第一个操作数
      operator: op, // 更新当前运算符
      isReadyForNewNum: true, // 标记准备输入新数字
      hasDecimalPoint: false,  // 重置小数点标记  // 标记当前数字是否已包含小数点
      completeExpression // 更新完整表达式
    });
  },

  /**
   * 计算两个数字的结果
   * @param {string} num1 - 第一个操作数
   * @param {string} num2 - 第二个操作数
   * @param {string} operator - 运算符
   * @return {string} 计算结果字符串
   * 处理除零错误并格式化结果
   */
  calculate(num1, num2, operator) {
    num1 = parseFloat(num1); // 转换为浮点数
    num2 = parseFloat(num2); // 转换为浮点数
    let result = 0;
    // 根据运算符进行计算
    switch(operator) {
      case "plus":
        result = num1 + num2;
        break;
      case "minus":
        result = num1 - num2;
        break;
      case "multiply":
        result = num1 * num2;
        break;
      case "divide":
        if (num2 === 0) {
          // 处理除零错误
          wx.showToast({
            title: '除数不能为零',
            icon: 'none',
            duration: 2000
          });
          return "错误";
        }
        result = num1 / num2;
        break;
    }
    
    // 格式化结果
    if (result.toString().includes('.')) {
      // 保留10位小数并去除末尾的0
      result = parseFloat(result.toFixed(10));
    }
    
    return result.toString();
  },

  /**
   * 计算最终结果
   * 构建完整表达式并保存到历史记录
   * 更新屏幕显示为计算结果
   */
  calculateResult() {
    let { screenData, expressionData, num1, operator } = this.data;
    
    if (num1 === "" || operator === "") {
      // 如果没有操作符或第一个数字，不需要计算
      return;
    }
    
    // 计算结果
    const result = this.calculate(num1, screenData, operator);
    
    // 构建并显示完整表达式：num1 operator num2 = result
    const operatorSymbol = this.getOperatorSymbol(operator);
    const fullExpression = `${num1} ${operatorSymbol} ${screenData} = ${result}`;
    
    // 保存计算历史
    this.saveHistory(fullExpression);
    
    // 更新界面
    // 更新页面数据
    this.setData({
      screenData: result, // 更新屏幕显示为计算结果
      expressionData: fullExpression, // 更新表达式显示为完整表达式
      num1: "",  // 清空第一个操作数  // 第一个操作数
      operator: "",  // 清空当前运算符  // 当前运算符
      isReadyForNewNum: true, // 标记准备输入新数字
      hasDecimalPoint: result.includes('.'), // 更新小数点标记  // 标记当前数字是否已包含小数点
      completeExpression: ""  // 清空完整表达式
    });
  },
  
  /**
   * 获取操作符符号
   * @param {string} op - 操作符类型
   * @return {string} 对应的显示符号
   */
  getOperatorSymbol(op) {
    switch(op) {
      case "plus": return "+";
      case "minus": return "-";
      case "multiply": return "×";
      case "divide": return "÷";
      default: return "";
    }
  },
  
  /**
   * 保存历史记录
   * @param {string} expression - 完整计算表达式
   * 将表达式保存到本地存储，最多保留20条
   */
  saveHistory(expression) {
    // 获取现有历史记录
    let historyList = wx.getStorageSync('calculatorHistory') || [];
    
    // 添加新记录到头部
    historyList.unshift({
      expression: expression,
      date: new Date().toLocaleString()
    });
    
    // 限制最多保存20条记录
    if (historyList.length > 20) {
      historyList = historyList.slice(0, 20);
    }
    
    // 保存到本地存储
    wx.setStorageSync('calculatorHistory', historyList);
  },

  /**
   * 点击按钮事件
   * @param {object} event - 点击事件对象
   * 根据按钮ID分发到对应的处理方法
   */
  clickButton(event) {
    const id = event.currentTarget.id;
    
    // 根据按钮ID执行相应操作
    switch (id) {
      case this.data.id_back:
        this.handleBackspace();
        break;
        
      case this.data.id_clear:
        this.clearScreen();
        break;
        
      case this.data.id_opo:
        this.toggleSign();
        break;
        
      case this.data.id_plus:
        this.handleOperator("plus");
        break;
        
      case this.data.id_minus:
        this.handleOperator("minus");
        break;
        
      case this.data.id_multiply:
        this.handleOperator("multiply");
        break;
        
      case this.data.id_divide:
        this.handleOperator("divide");
        break;
        
      case this.data.id_equal:
        this.calculateResult();
        break;
        
      case this.data.id_dot:
        this.appendDecimalPoint();
        break;
        
      case this.data.id_url:
        this.goToHistory();
        break;
        
      case this.data.id_0:
      case this.data.id_1:
      case this.data.id_2:
      case this.data.id_3:
      case this.data.id_4:
      case this.data.id_5:
      case this.data.id_6:
      case this.data.id_7:
      case this.data.id_8:
      case this.data.id_9:
        this.appendNumber(id);
        break;
    }
  },

  /**
   * 跳转到历史记录页面
   * 使用wx.navigateTo导航到list页面
   */
  goToHistory() {
    wx.navigateTo({
      url: '/pages/list/list'
    });
  },

  // 生命周期函数--监听页面初次渲染完成
  onReady() {
  },

  // 生命周期函数--监听页面显示
  onShow() {
  },

  // 生命周期函数--监听页面隐藏
  onHide() {
  },

  // 生命周期函数--监听页面卸载
  onUnload() {
  },

  // 页面相关事件处理函数--监听用户下拉动作
  onPullDownRefresh() {
  },

  // 页面上拉触底事件的处理函数
  onReachBottom() {
  },

  // 用户点击右上角分享
  onShareAppMessage() {
  }
})